﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;
using IEx.Common;
using IEx.Common.Sources;
using IEx.Model.Partials;
using IEx.Utilities;

namespace IEx.ParserBuilder.Chotot
{
    public class ChototParser : IHtmlParser
    {        

        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <param name="html"></param>
        /// <param name="attachResultItem"></param>
        /// <param name="attachNewItemSource"></param>
        public void Parse(SourceItem item, string html, Action<Model.Partials.Announcement> attachResultItem, Action<SourceItem> attachNewItemSource)
        {
            try
            {
                string tableId = "class=\"listing-rows\"";
                string footerId = "class=\"nohistory adwatch_star\"";
                Uri newUri = Utility.CreateNewUriForNextPage(item.Url, 1);
                List<Announcement> detectedAnnouncements = new List<Announcement>();
                string remainHtml = Utility.GetHtmlBody(html, tableId, footerId);

                if (!string.IsNullOrEmpty(remainHtml))
                {

                    Regex regList = new Regex("<div class=\"chotot-list-row.*?\">.*?class=\"clear_row\"></div></div>");
                    MatchCollection mList = regList.Matches(remainHtml);
                    for (int i = 0; i < mList.Count; i++)
                    {
                        string titleAds = string.Empty;
                        string linkDetails = string.Empty;
                        string dateTime = string.Empty;
                        string location = string.Empty;
                        string price = string.Empty;
                        string category = string.Empty;
                        string content = string.Empty;
                        DateTime postDate = DateTime.MinValue;
                        List<string> atts = new List<string>();

                        string itemHtml = mList[i].Value.Trim();
                        //Extract info item
                        Regex regTitle = new Regex("<a\\s title=\".*?\" href=\".*?\" class=\"ad-subject\">.*?</a>");
                        Match mTitle = regTitle.Match(itemHtml);
                        if (mTitle.Success)
                        {
                            string titleHtml = mTitle.Value.Trim();
                            titleAds = HttpUtility.HtmlDecode(RegexUtility.ExtractTextFromHtmlTag(titleHtml).Trim());
                            linkDetails = RegexUtility.ExtractHyperlink(titleHtml);
                        }

                        Regex regPrice = new Regex("<div class=\"ad-price\">.*?</div>");
                        Match mPrice = regPrice.Match(itemHtml);
                        if (mPrice.Success)
                        {
                            string priceHtml = mPrice.Value.Trim();
                            price = RegexUtility.ExtractTextFromHtmlTag(priceHtml).Trim();
                        }

                        Regex regCate = new Regex("<a onclick=\".*?\" class=\"ad-category-region\" href=\".*?\" title=\".*?\">.*?</a>");
                        Match mCate = regCate.Match(itemHtml);
                        if (mCate.Success)
                        {
                            string cateHtml = mCate.Value.Trim();
                            category = HttpUtility.HtmlDecode(RegexUtility.ExtractTextFromHtmlTag(cateHtml).Trim());
                        }

                        Regex regTime = new Regex("<div nowrap=\"nowrap\" class=\"listing_thumbs_date\">.*?</div>");
                        Match mTime = regTime.Match(itemHtml);
                        if (mTime.Success)
                        {
                            string timeHtml = mTime.Value.Trim();
                            dateTime = RegexUtility.ExtractTextFromHtmlTag(timeHtml).Trim();
                            postDate = Utility.ConvertVnDateTimeObject(dateTime,item.DateTimeFormat);
                        }

                        if (!string.IsNullOrEmpty(linkDetails))
                        {
                            //Extract detail info item
                            content = HttpUtility.HtmlDecode(ExtractClassifiedAdsDetailForChotot(linkDetails, item,ref atts).Trim());
                        }

                        if (!string.IsNullOrEmpty(linkDetails) && !string.IsNullOrEmpty(content) && !string.IsNullOrEmpty(titleAds))
                        {
                            Announcement ann = new Announcement();
                            ann.SourceId = item.SourceId;
                            ann.SourceCode = item.SourceCode;
                            ann.DateTime = postDate;
                            ann.Message = content;
                            ann.Title = titleAds;
                            ann.PressrelaseCate = category;
                            ann.LangId = item.LangId;
                            ann.InsertedDate = DateTime.Now;
                            ann.Link = linkDetails;
                            ann.Attachment = false;
                            ann.AttachmentLinks = atts;
                            ann.MessageTypeId = 0;
                            detectedAnnouncements.Add(ann);
                        }
                    }
                    //Extract url next page
                    Regex regNextPage = new Regex("<span class=\"pagination_span.*?\">.*?<a class=\"pagination_link\".*?</a>");
                    Match mNextPage = regNextPage.Match(remainHtml);
                    if (mNextPage.Success)
                    {
                        string nextPageHtml = mNextPage.Value.Trim();
                        string link = RegexUtility.ExtractHyperlink(nextPageHtml);
                        item.Url = link;
                        Uri uriNextPage = new Uri(link);
                        var query = HttpUtility.ParseQueryString(uriNextPage.Query);
                        var numberOfPage = query.Get("o");
                        if (int.Parse(numberOfPage) == Settings.NUMBER_OF_PAGE_REQUEST)
                            item.Url = string.Empty;
                    }
                    else
                    {
                        item.Url = string.Empty;
                    }
                }
                if (!string.IsNullOrEmpty(item.Url))
                {
                    SourceItem nItem = new SourceItem(item.Url, item.LangId, item.SourceCode, item.SearchCode, item.SourceId, item.DateTimeFormat);
                    if (!string.IsNullOrEmpty(item.RequestBuilderType))
                        nItem.RequestBuilderType = item.RequestBuilderType;

                    if (!string.IsNullOrEmpty(item.HtmlParserType))
                        nItem.HtmlParserType = item.HtmlParserType;

                    nItem.PrevResponseHtml = html;
                    attachNewItemSource(nItem);
                }
                // insert into download queue when no error in parsing
                foreach (Announcement ann in detectedAnnouncements)
                {
                    attachResultItem(ann);
                }
            }
            catch (Exception ex)
            {
                // if has an error, save fail request to next time scanning
                if (item.FailId == 0)
                {
                    item.FailId = DateTime.Now.Ticks;
                    Utility.SaveFailRequests(item);
                }

                // then write log
                string message = string.Format(@"
            Company code:   {0}
            HTML Parsing:   Fail
            Request URL:    {1}
            Search key:     {2}", item.SourceCode, item.Url, item.SearchCode);
                Logger.WriteError(message, ex);
            }
        }

        #region Methods to extract ClassifiedAds

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="item"></param>
        /// <param name="classifiedAds"></param>
        private static string ExtractClassifiedAdsDetailForChotot(string url, SourceItem item, ref List<string> atts)
        {
            //int milliseconds = 1000;
            //Thread.Sleep(milliseconds);//Set time out after 2 seconds to request next

            Logger.Debug("***SCANNING NEWS CLASSIFIEDADS DETAILS URL: " + url);
            HttpStatusCode status = HttpStatusCode.Accepted;
            string html = Utility.LoadHtml(url, ref status);
            string content = string.Empty;
            try
            {
                if (!string.IsNullOrEmpty(html))
                {
                    string infoFullId = "id=\"container\"";
                    string otherNewsId = "id=\"menu-container\"";
                    string remainHtml = Utility.GetHtmlBody(html, infoFullId, otherNewsId);

                    if (!string.IsNullOrEmpty(remainHtml))
                    {
                        Regex regContent = new Regex("<div class=\"body_text\">(.|\n).*?</div>");
                        Match mContent = regContent.Match(remainHtml);
                        if (mContent.Success)
                        {
                            string contentHtml = mContent.Value.Trim();
                            content = RegexUtility.ExtractTextFromHtmlTag(contentHtml);
                        }

                        Regex regImages = new Regex("class=\"ad_thumb.*?\".*?>.*?</div>");
                        MatchCollection mImages = regImages.Matches(remainHtml);
                        for (int i = 0; i < mImages.Count; i++)
                        {
                            string imageHtml = mImages[i].Value.Trim();
                            Regex regPhoto = new Regex("showLargeImage.*?(\\w\\s|)\\)");
                            Match mPhoto = regPhoto.Match(imageHtml);
                            if (mPhoto.Success)
                            {
                                string photoHtml = mPhoto.Value.Trim();
                                string linkPhoto = photoHtml.Replace("showLargeImage('", string.Empty).Replace("')", string.Empty);
                                atts.Add(linkPhoto);
                            }
                        }

                        Regex regImageDefaultBox = new Regex(" <div id=\"display_image\".*?<div");
                        Match mImageDefaultBox = regImageDefaultBox.Match(remainHtml);
                        if (mImageDefaultBox.Success)
                        {
                            string imageDefaultBoxHtml = mImageDefaultBox.Value.Trim();
                            Regex regImageDefault = new Regex("<img src=\".*?\" id=\"main_image\".*?>");
                            Match mImageDefault = regImageDefault.Match(imageDefaultBoxHtml);
                            if (mImageDefault.Success)
                            {
                                string photoHtml = mImageDefault.Value.Trim();
                                string linkPhoto = RegexUtility.ExtractSrcFromImgTag(photoHtml);
                                if (atts.Count == 0)
                                {
                                    atts.Add(linkPhoto);
                                }
                            }
                        }
                    }
                }
                return content;
            }
            catch (Exception ex)
            {
                // if has an error, save fail request to next time scanning
                if (item.FailId == 0)
                {
                    item.FailId = DateTime.Now.Ticks;
                    Utility.SaveFailRequests(item);
                }

                // then write log
                string message = string.Format(@"
            Extract news classified ads details
            Source code:   {0}
            HTML Parsing:   Fail
            Request URL:    {1}", item.SourceCode, url);
                Logger.WriteError(message, ex);
                return string.Empty;
            }
        }

        #endregion
    }
}
